package com.foreverwin.jzymes.production.grind.service.impl;

import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.common.util.BOHandleUtil;
import com.foreverwin.jzymes.common.util.CommonMethods;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.production.grind.domain.GrindCheck;
import com.foreverwin.jzymes.production.grind.domain.GrindCheckNc;
import com.foreverwin.jzymes.production.grind.mapper.GrindCheckMapper;
import com.foreverwin.jzymes.production.grind.mapper.GrindCheckNcMapper;
import com.foreverwin.jzymes.production.grind.service.IGrindCheckAdviceService;
import com.foreverwin.jzymes.production.sfc.mapper.SFCMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class GrindCheckAdviceServiceImpl implements IGrindCheckAdviceService {

    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IItemGroupAdviceService itemGroupAdviceService;
    @Autowired
    IResourceAdviceService resourceAdviceService;
    @Autowired
    IItemAdviceService itemAdviceService;
    @Autowired
    ICommonService commonService;
    @Autowired
    INCCodeAdviceService ncCodeAdviceService;
    @Autowired
    SFCMapper sfcMapper;
    @Autowired
    GrindCheckMapper grindCheckMapper;
    @Autowired
    GrindCheckNcMapper grindCheckNcMapper;

    /**
     * 研磨检验
     *
     * @param grindCheck
     * @param grindCheckNcs
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void grindCheck(GrindCheck grindCheck, List<GrindCheckNc> grindCheckNcs ){

        grindCheck.setCreateUserBo( CommonMethods.getUserBo() );
        grindCheck.setCreatedDateTime( new Date());
        grindCheck.setHandle( BOHandleUtil.buildGrindCheckHandle( grindCheck.getSite(), grindCheck.getItemBo(), grindCheck.getCreatedDateTime() ) );

        /**更新研磨工令良品产出数量，保存良品过站记录*/
        processGrindCheck( grindCheck );

        /**更新研磨工令制程报废数量，保存不良数据*/
        processGrindCheckNcs( grindCheck, grindCheckNcs );

        /**保存检验记录*/
        grindCheckMapper.insertGrindCheck( grindCheck );
        for( GrindCheckNc grindCheckNc : grindCheckNcs ){
            grindCheckNcMapper.insertGrindCheckNc( grindCheckNc );
        }
    }

    /**
     * 检查研磨检验字段
     *
     * @param grindCheck
     */
    public void checkFieldsForGrindCheck( GrindCheck grindCheck ){
        /**检查站点*/
        siteAdviceService.existSite( grindCheck.getSite() );
        /**检查机种*/
        /*String itemGroup = itemGroupAdviceService.findItemGroupBySite( grindCheck.getSite() );
        Assert.hasText( itemGroup, I18nUtil.getI18nText( "common.itemGroupNotExist", new String[]{ itemGroup } ) );
        grindCheck.setMachineType( itemGroup );*/
        String itemGroup = commonService.findItemGroupByItem( grindCheck.getSite(), grindCheck.getItemBo() );
        grindCheck.setMachineType( itemGroup );
        /**检查设备*/
        resourceAdviceService.existResource( grindCheck.getSite(), grindCheck.getResrce() );
        /**检查物料*/
        itemAdviceService.existItem( grindCheck.getItemBo() );
        /**检查检验良品数量数量、不良品数量*/
        Assert.isTrue( ( grindCheck.getOkQty() != null && grindCheck.getOkQty() > 0 ) || ( grindCheck.getNcQty() != null && grindCheck.getNcQty() > 0 ), I18nUtil.getI18nText("production.grind.okQtyAndNcQtyNotValid",new Object[]{ grindCheck.getOkQty(), grindCheck.getNcQty() }));
        /**检验时间不能为空*/
        Assert.notNull( grindCheck.getCheckTime(), I18nUtil.getI18nText( "production.grind.checkTimeNotNull" ) );
    }

    /**
     * 更新研磨工令良品产出数量，保存良品过站记录
     *
     * @param grindCheck
     */
    public void processGrindCheck( GrindCheck grindCheck ){
        /**检查字段*/
        checkFieldsForGrindCheck( grindCheck );

        Long okQty = grindCheck.getOkQty();
        if( okQty != null && okQty > 0 ) {
            /**检验合格数量放在研磨产出录入过站*/
            //commonService.updateGrindSfcForPass( grindCheck.getSite(), grindCheck.getItemBo(), okQty, grindCheck.getResrce(), grindCheck.getCreatedDateTime()  );
        }
    }

    /**
     * 检查不良明细字段
     *
     * @param grindCheckNc
     */
    public void checkFieldsForGrindCheckNc( GrindCheck grindCheck, GrindCheckNc grindCheckNc ){
        /**检查不合格代码是否存在*/
        ncCodeAdviceService.existNCCode( grindCheck.getSite(), grindCheckNc.getNcCode() );
        /**检查不良明细可重工数量和不可重工数量是否有效*/
        Assert.isTrue( ( grindCheckNc.getReworkQty() != null && grindCheckNc.getReworkQty() > 0 ) || ( grindCheckNc.getScrapQty() != null && grindCheckNc.getScrapQty() > 0 ), I18nUtil.getI18nText( "production.grind.reworkQtyAndScrapQtyNotValid", new Object[]{grindCheckNc.getReworkQty(),grindCheckNc.getScrapQty()} ) );
    }

    /**
     * 更新研磨工令制程报废数量，保存不良数据
     *
     * @param grindCheck
     * @param grindCheckNcs
     */
    public void processGrindCheckNcs( GrindCheck grindCheck, List<GrindCheckNc> grindCheckNcs ){
        Long totalNcQty = 0L;
        String itemBo = commonService.findSfcItemByItem( grindCheck.getSite(), grindCheck.getItemBo() );

        List<String> ncCodeList = new ArrayList<>();
        for( GrindCheckNc grindCheckNc : grindCheckNcs ){
            /**检查不良明细字段*/
            checkFieldsForGrindCheckNc( grindCheck, grindCheckNc );

            if( ncCodeList.contains( grindCheckNc.getNcCode() ) ){
                throw BusinessException.build( "production.grind.ncCodeDuplicate", new String[]{ grindCheckNc.getNcCode() } );
            }
            ncCodeList.add( grindCheckNc.getNcCode() );

            Long reworkQty = grindCheckNc.getReworkQty() == null ? 0 : grindCheckNc.getReworkQty();
            Long scrapQty = grindCheckNc.getScrapQty() == null ? 0 : grindCheckNc.getScrapQty();

            totalNcQty += reworkQty + scrapQty;

            /**更新工令已下达数量、制程报废数量，保存不良明细*/
            if( scrapQty > 0 ){
                commonService.updateGrindSfcForScrap( grindCheck.getSite(), itemBo, grindCheck.getResrce(), grindCheckNc.getNcCode(), grindCheckNc.getScrapQty(), grindCheck.getCreatedDateTime() );
            }
            grindCheckNc.setGrindCheckBo( grindCheck.getHandle() );
            grindCheckNc.setHandle(BOHandleUtil.buildGrindCheckNcHandle( grindCheck.getHandle(), grindCheckNc.getNcCode() ));
        }

        /**检查不良数量和不良明细不良数量是否匹配*/
        Assert.isTrue( totalNcQty == grindCheck.getNcQty(), I18nUtil.getI18nText( "production.grind.ncQtyNotMatchDetailNcQty", new Object[]{ grindCheck.getNcQty(), totalNcQty } ) );
    }


}
